/*
 * Copyright (C) 2007  Vianney le Clément
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package fsahoraires.util;

import java.util.*;

import org.w3c.dom.*;

public class DOMUtils {

	/**
	 * Wrapper pour NodeList
	 * 
	 * @param list
	 * @return
	 */
	public static List<Node> list(final NodeList list) {
		return new AbstractList<Node>() {
			public int size() {
				return list.getLength();
			}

			public Node get(int index) {
				Node item = list.item(index);
				if (item == null)
					throw new IndexOutOfBoundsException();
				return item;
			}
		};
	}

	public static List<Node> getElementsByTagName(Element e, String tag) {
		return list(e.getElementsByTagName(tag));
	}

	/**
	 * Renvoie les éléments enfants (uniquement de type ELEMENT)
	 * 
	 * @param e
	 * @return
	 */
	public static Iterable<Element> getChildElements(final Element e) {
		return new Iterable<Element>() {
			public Iterator<Element> iterator() {
				final NodeList list = e.getChildNodes();
				int i = 0;
				for (; i < list.getLength(); i++) {
					if (list.item(i).getNodeType() == Node.ELEMENT_NODE)
						break;
				}
				final int init = i;
				return new Iterator<Element>() {
					int cur = init;

					public void remove() {
						throw new UnsupportedOperationException();
					}

					public Element next() {
						Element item = (Element) list.item(cur);
						for (cur++; cur < list.getLength(); cur++) {
							if (list.item(cur).getNodeType() == Node.ELEMENT_NODE)
								break;
						}
						return item;
					}

					public boolean hasNext() {
						return cur < list.getLength();
					}

				};
			}
		};
	}

	/**
	 * Renvoie le premier élément avec le tag correspondant
	 * 
	 * @param e
	 * @param tag
	 * @return
	 */
	public static Element getTag(Element e, String tag) {
		NodeList list = e.getElementsByTagName(tag);
		if (list.getLength() > 0)
			return (Element) list.item(0);
		else
			return null;
	}

	/**
	 * Renvoie le premier élément avec le tag correspondant
	 * 
	 * @param d
	 * @param tag
	 * @return
	 */
	public static Element getTag(Document d, String tag) {
		NodeList list = d.getElementsByTagName(tag);
		if (list.getLength() > 0)
			return (Element) list.item(0);
		else
			return null;
	}

	/**
	 * Renvoie le texte contenu dans un élément
	 * 
	 * @param node
	 * @return
	 */
	public static String getText(final Node node) {
		Node text = node.getFirstChild();
		if (text == null)
			return "";
		return text.getNodeValue();
	}

	/**
	 * Renvoie le texte contenu dans le premier tag rencontré.
	 * 
	 * @param e
	 * @param tag
	 * @return
	 */
	public static String getTagText(final Element e, final String tag) {
		return getText(e.getElementsByTagName(tag).item(0));
	}

	/**
	 * Crée un élément avec un Text Node comme enfant.
	 * 
	 * @param doc
	 * @param tagName
	 * @param text
	 * @return
	 */
	public static Element createElementWithText(final Document doc,
			final String tagName, final String text) {
		Element e = doc.createElement(tagName);
		e.appendChild(doc.createTextNode(text));
		return e;
	}

}
